#ifndef TESTGRPCSERVER_H
#define TESTGRPCSERVER_H
#include "stdfax.h"
#include "IgRpcService.h"

#include <iostream>
#include <memory>
#include <string>
#include <thread>

//异步使用
#include <grpc/support/log.h>

//grpc 客户端相关的头文件
#include "grpcpp/grpcpp.h"
#include "grpc/grpc.h"
#include "grpcpp/channel.h"
#include "grpcpp/client_context.h"
#include "grpcpp/create_channel.h"
#include "grpcpp/security/credentials.h"


//包含grpc 相关的类，之后可调用内部的接口方法。
using grpc::Channel;
using grpc::ClientContext;
using grpc::ClientReader;
using grpc::ClientReaderWriter;
using grpc::ClientWriter;
using grpc::Status;

//异步使用
using grpc::ClientAsyncResponseReader;
using grpc::CompletionQueue;

//eg. 包含上边的include和grpc类，可满足grpc的四种调用类型

//以下的头文件和接口类，由业务端实现

//start-----由业务端实现
#include "helloworld.grpc.pb.h"

using helloworld::Greeter;
using helloworld::HelloReply;
using helloworld::HelloRequest;
//end-----由业务端实现


class GreeterSynClient {
 public:
  GreeterSynClient(std::shared_ptr<Channel> channel);

  // Assembles the client's payload, sends it and presents the response back
  // from the server.
  std::string SayHello(const std::string& user);

 private:
  std::unique_ptr<Greeter::Stub> stub_;
};

class GreeterAsynClient {
 public:
  explicit GreeterAsynClient(std::shared_ptr<Channel> channel);

  // Assembles the client's payload, sends it and presents the response back from the server.
  std::string SayHello(const std::string& user);

 private:
  std::unique_ptr<Greeter::Stub> stub_;
};

#if 1
class GreeterAsynClient2 {
 public:
  explicit GreeterAsynClient2(std::shared_ptr<Channel> channel);

  // Assembles the client's payload and sends it to the server.
  void SayHello(const std::string& user);

  // Loop while listening for completed responses.
  // Prints out the response from the server.
  void AsyncCompleteRpc(void);

 private:
  // struct for keeping state and data information
  struct AsyncClientCall {
    // Container for the data we expect from the server.
    HelloReply reply;

    // Context for the client. It could be used to convey extra information to
    // the server and/or tweak certain RPC behaviors.
    ClientContext context;

    // Storage for the status of the RPC upon completion.
    Status status;

    std::unique_ptr<ClientAsyncResponseReader<HelloReply>> response_reader;
  };

  std::unique_ptr<Greeter::Stub> stub_;
  CompletionQueue cq_;
};

#endif

//class TestGRPCClient : public IGRPCService 如果需要IGRPCService接口内容，直接获取服务接口
class TestGRPCClient : public IService
{
public:
    static TestGRPCClient * Instance();

    //gRPC测试客户端同步调用
    /*配置文件，须传递服务的IP和端口信息，比如 0.0.0.0:50051 */
    virtual void OSGI_API TestgRPCSynClientRun(std::string server_address);

    //gRPC测试客户端异步调用
    /*配置文件，须传递服务的IP和端口信息，比如 0.0.0.0:50051 */
    virtual void OSGI_API TestgRPCAsynClientRun(std::string server_address);

    //gRPC测试客户端异步调用
    /*配置文件，须传递服务的IP和端口信息，比如 0.0.0.0:50051 */
    virtual void OSGI_API TestgRPCAsynClient2Run(std::string server_address);

private:
    TestGRPCClient(void);
    ~TestGRPCClient(void);

private:
    static TestGRPCClient * m_pInstance;
    GreeterSynClient * Syngreeter;             //同步方法实现的类
    GreeterAsynClient * Asyngreeter;           //异步方法实现的类
    GreeterAsynClient2 * Asyngreeter2;         //异步方法二实现的类
};

#endif // TESTGRPCSERVER_H
